package main
import (
	"fmt"
	"reflect"
)
type Student struct{
	Name string `json:"username" format:"UseName"`
	Age int	`json:"age"  format:"UseAge"`
	Score int `json:"score"`
}
func (Self *Student)SetValue(name string,age int,score int){
	Self.Name=name
	Self.Age=age
	Self.Score=score
}
func (Self Student)PrintStudent(){
	fmt.Printf("name=%s  age=%d   score=%d\n",Self.Name,Self.Age,Self.Score)
}
func PrintStructField(x interface{}){
	v:=reflect.TypeOf(x)
	if v.Kind()!=reflect.Struct&&v.Elem().Kind()!=reflect.Struct{
		fmt.Printf("x不是结构体")
		return
	}
	field0:=v.Field(0)
	fmt.Printf("%#v\n",field0)
	fmt.Printf("字段的名称:%v\n",field0.Name)
	fmt.Printf("字段的类型:%v\n",field0.Type)
	fmt.Printf("字段的Tag:%v\n",field0.Tag.Get("json"))
	fmt.Printf("字段的Tag:%v\n",field0.Tag.Get("format"))

	field1,ok:=v.FieldByName("Age")
	if ok{
		fmt.Println("字段名称:",field1.Name)
		fmt.Println("字段类型:",field1.Type)
		fmt.Println("字段Tag:",field1.Tag.Get("json"))
		fmt.Println("字段Tag:",field1.Tag.Get("format"))
	}

	fieldCount:=v.NumField()
	fmt.Println("结构有",fieldCount,"个属性")
	value:=reflect.ValueOf(x)
	for i:=0;i<fieldCount;i++{
		fmt.Printf("类型的名称:%v,类型的值:%v,类型的种类:%v,类型的Tag:%v\n",v.Field(i).Name,value.Field(i),v.Field(i).Type,v.Field(i).Tag.Get("json"))
	}
}

func PrintStructFn(s interface{}){
	t:=reflect.TypeOf(s)
	v:=reflect.ValueOf(s)
	if(t.Kind()!=reflect.Struct&&t.Elem().Kind()!=reflect.Struct){
		fmt.Printf("传入的参数不是结构体\n")
		return
	}
	method0:=t.Method(0)
	fmt.Println(method0.Name)
	fmt.Println(method0.Type)
	method1,ok:=t.MethodByName("PrintStruct")
	if ok==true{
		fmt.Println(method1.Name)
		fmt.Println(method1.Type)
	}
	fmt.Printf("-----------------------------\n")
	info1:=v.MethodByName("PrintStudent").Call(nil)
	//info1:=v.MethodByName("SetValue").Call(nil)
	fmt.Println(info1)

	var params []reflect.Value
	params=append(params,reflect.ValueOf("李四"))
	params=append(params,reflect.ValueOf(23))
	params=append(params,reflect.ValueOf(99))
	v.MethodByName("SetValue").Call(params)

	info2:=v.MethodByName("PrintStudent").Call(nil)
	fmt.Println(info2)

	fmt.Println("方法数量:",t.NumMethod())
	fmt.Println(s)
}

func main(){
	var stu Student
	stu.SetValue("张三",18,98)
	fmt.Println(stu)
	PrintStructField(stu)
	PrintStructFn(&stu)
	fmt.Println(stu)
}